﻿using System;
using System.Collections.Generic;
using System.Text;
using Quartz;
using ShootSearch.Util.Serializers;
using System.Xml.Serialization;
using ShootSearch.Util;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;

namespace ShootSearch.Core
{
    [Serializable]
    [TypeConverter(typeof(ExpandableConverter<TaskConfig>))]
    public class TaskConfig: IXmlSerializable
    {
        public const int MINI_MEM_LOG_SIZE = 128;
        public const string TASKFILE = "Task.config";

        public string TaskName { get; set; }

        /// <summary>
        /// Task launch type
        /// </summary>
        public LaunchType LaunchType { get; set; }

        /// <summary>
        /// The log size in memory, in char length, default 8192 , minimum value is 128 (ignore less than 128)
        /// </summary>
        public int MemoryLogSize { get; set; }

        public List<JobConfig> Jobs { get; set; }

        protected string contextPath = string.Empty;
        [XmlIgnore]
        public string ContextPath
        {
            get { return contextPath; }
            set
            {
                if (value != null)
                {
                    contextPath = value.ToLower();
                }
            }
        }

        [XmlIgnore]
        public Task Task { get; set; }

        public TaskConfig()
        {
            Jobs = new List<JobConfig>();
            MemoryLogSize = 8192;
        }

        public void Save(string path)
        {
            XmlFormatter.ToXmlFile(this, path);
        }

        public JobDetail GetCurrentJob()
        {
            if (Jobs==null || Jobs.Count == 0) return null;
            JobDetail root = GetJobDetail(Jobs[0]);
            JobDetail current = root;
            for (int i = 1; i < Jobs.Count; i++)
            {
                JobDetail next = GetJobDetail(Jobs[i]);
                current.JobDataMap.Add(Task.JOB_NEXT, next);
                current = next;
            }
            return root;
           
        }

        public JobDetail GetJobDetail(JobConfig jobConfig)
        {
            if (jobConfig != null && jobConfig.Type != null)
            {
                ISpiderMan job = jobConfig.GetObjectWithConfig() as ISpiderMan;
                JobDetail detail = new JobDetail(jobConfig.Name, null, job.GetType());
                detail.JobDataMap.Add(Task.JOB_CONFIG, job.Config);
                detail.JobDataMap.Add(Task.JOB_CONTEXT_PATH, this.ContextPath);

                return detail;
            }
            return null;
        }

        public static TaskConfig Load(string path)
        {
            TaskConfig config = new TaskConfig();
            config = XmlFormatter.FromFile(path, config.GetType()) as TaskConfig;
            if (config == null) return null;
            else
            {
                config.ContextPath = IO.FormatDirName(new FileInfo(path).Directory.FullName);
                return config;
            }
        }
        
        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return new System.Xml.Schema.XmlSchema();
        }

        public void ReadXml(XmlReader reader)
        {
            if (reader.ReadToFollowing("TaskName"))
            {
                TaskName = reader.ReadString();
            }

            if (reader.ReadToFollowing("LaunchType"))
            {
                object objValue = Enum.Parse(typeof(LaunchType), reader.ReadString());
                if (objValue != null)
                {
                    LaunchType = (LaunchType)objValue;
                }
            }

            if (reader.ReadToFollowing("MemoryLogSize"))
            {
                MemoryLogSize = reader.ReadElementContentAsInt();
            }

            reader.ReadToFollowing("Jobs");
            while (reader.ReadToFollowing("Job"))
            {
                JobConfig job = XmlFormatter.FromXml(reader, new JobConfig().GetType()) as JobConfig;
                if (job != null)
                {
                    Jobs.Add(job);
                }
            }

        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement("TaskName");
            writer.WriteString(TaskName);
            writer.WriteEndElement();

            writer.WriteStartElement("LaunchType");
            writer.WriteString(LaunchType.ToString());
            writer.WriteEndElement();

            writer.WriteStartElement("MemoryLogSize");
            writer.WriteValue(MemoryLogSize);
            writer.WriteEndElement();

            writer.WriteStartElement("Jobs");
            for (int i = 0; i < Jobs.Count; i++)
            {
                XmlFormatter.ToXml(writer, Jobs[i]);
            }
            writer.WriteEndElement();
        }

        #endregion

    }

    public enum LaunchType
    { 
        /// <summary>
        /// Launched manually
        /// </summary>
        Manually,
        /// <summary>
        /// Launched once created
        /// </summary>
        AutomaticallyOnce,
        /// <summary>
        /// Launched every created time
        /// </summary>
        AutomaticallyAlways
    }
   
}
